package view;

import service.ClassroomService;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.Map;

// 教室管理面板类，继承自JPanel，用于实现教室管理的可视化界面
//黄嘉毅
public class ClassroomManagementPanel extends JPanel {
    // 标题字体，使用微软雅黑，加粗，大小14
    private static final Font TITLE_FONT = new Font("微软雅黑", Font.BOLD, 14);
    // 内容字体，使用微软雅黑，常规，大小13
    private static final Font CONTENT_FONT = new Font("微软雅黑", Font.PLAIN, 13);

    // 用于显示教室信息的表格
    private JTable classroomTable;
    // 表格的数据模型
    private DefaultTableModel tableModel;
    // 教室服务对象，用于处理与教室相关的业务逻辑
    private ClassroomService classroomService;

    // 构造函数，初始化组件并加载教室数据
    public ClassroomManagementPanel() {
        this.classroomService = new ClassroomService();
        initComponents();
        loadClassroomData();
    }

    // 初始化组件的方法
    private void initComponents() {
        // 设置面板布局为BorderLayout，组件间水平和垂直间距为10
        setLayout(new BorderLayout(10, 10));
        // 设置面板边框为10像素的空白边框
        setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        // 工具栏面板，使用FlowLayout左对齐
        JPanel toolBar = new JPanel(new FlowLayout(FlowLayout.LEFT));
        // 添加按钮
        JButton addButton = new JButton("添加教室");
        addButton.setFont(CONTENT_FONT);
        // 为添加按钮添加点击事件监听器，点击时显示添加教室对话框
        addButton.addActionListener(e -> showAddDialog());
        toolBar.add(addButton);

        // 将工具栏添加到面板的北部
        add(toolBar, BorderLayout.NORTH);

        // 定义表格的列名
        String[] columnNames = {"教学楼", "教室号", "楼层", "容量", "教室类型", "状态", "操作"};
        // 创建表格数据模型，设置行数为0，并覆盖isCellEditable方法，使只有操作列可编辑
        tableModel = new DefaultTableModel(columnNames, 0) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return column == columnNames.length - 1;
            }
        };

        // 创建表格，使用上述数据模型
        classroomTable = new JTable(tableModel);
        classroomTable.setFont(CONTENT_FONT);
        // 设置表格表头字体
        classroomTable.getTableHeader().setFont(TITLE_FONT);
        // 设置表格行高为35
        classroomTable.setRowHeight(35);
        // 设置表格选择模式为单选
        classroomTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        // 获取操作列
        TableColumn operationColumn = classroomTable.getColumnModel().getColumn(6);
        // 设置操作列的渲染器为自定义的ButtonRenderer
        operationColumn.setCellRenderer(new view.common.ButtonRenderer());
        // 设置操作列的编辑器为自定义的ButtonEditor，处理按钮点击事件
        operationColumn.setCellEditor(new view.common.ButtonEditor(e -> {
            int row = classroomTable.getSelectedRow();
            if (row >= 0) {
                // 获取当前选中行的教学楼和教室号
                String building = (String) tableModel.getValueAt(row, 0);
                String roomNumber = (String) tableModel.getValueAt(row, 1);
                // 获取按钮的动作命令
                String action = e.getActionCommand();

                SwingUtilities.invokeLater(() -> {
                    if ("编辑".equals(action)) {
                        // 点击编辑按钮，显示编辑对话框
                        showEditDialog(building, roomNumber);
                    } else if ("删除".equals(action)) {
                        // 点击删除按钮，删除教室
                        deleteClassroom(building, roomNumber);
                    }
                });
            }
        }));

        // 设置操作列的首选宽度和最小宽度
        operationColumn.setPreferredWidth(150);
        operationColumn.setMinWidth(150);

        // 设置其他列的宽度
        int[] columnWidths = {100, 100, 60, 80, 100, 80, 150};
        for (int i = 0; i < columnWidths.length; i++) {
            TableColumn column = classroomTable.getColumnModel().getColumn(i);
            column.setPreferredWidth(columnWidths[i]);
        }

        // 将带有表格的滚动面板添加到面板的中心
        add(new JScrollPane(classroomTable), BorderLayout.CENTER);
    }

    // 显示添加教室对话框的方法
    private void showAddDialog() {
        // 创建模态对话框
        JDialog dialog = new JDialog((Frame) SwingUtilities.getWindowAncestor(this),
                "添加教室", true);
        dialog.setLayout(new BorderLayout(10, 10));

        // 创建表单面板，使用GridBagLayout布局
        JPanel formPanel = new JPanel(new GridBagLayout());
        formPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // 创建教学楼文本框
        JTextField buildingField = new JTextField(20);
        // 创建教室号文本框
        JTextField roomNumberField = new JTextField(20);
        // 创建楼层微调器，初始值1，最小值1，最大值100，步长1
        JSpinner floorSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 100, 1));
        // 创建容量微调器，初始值30，最小值1，最大值200，步长1
        JSpinner capacitySpinner = new JSpinner(new SpinnerNumberModel(30, 1, 200, 1));
        // 创建教室类型下拉框
        JComboBox<String> typeCombo = new JComboBox<>(new String[]{"普通教室", "上机室", "多媒体教室","阶梯教室","其他教室"});
        // 创建状态下拉框
        JComboBox<String> statusCombo = new JComboBox<>(new String[]{"可用", "维修中", "已停用"});

        // 添加表单字段到表单面板
        addFormField(formPanel, "教学楼：", buildingField, gbc, 0);
        addFormField(formPanel, "教室号：", roomNumberField, gbc, 1);
        addFormField(formPanel, "楼层：", floorSpinner, gbc, 2);
        addFormField(formPanel, "容量：", capacitySpinner, gbc, 3);
        addFormField(formPanel, "教室类型：", typeCombo, gbc, 4);
        addFormField(formPanel, "状态：", statusCombo, gbc, 5);

        // 将表单面板添加到对话框的中心
        dialog.add(formPanel, BorderLayout.CENTER);

        // 创建按钮面板，使用FlowLayout居中对齐
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        // 创建保存按钮
        JButton saveButton = new JButton("保存");
        // 创建取消按钮
        JButton cancelButton = new JButton("取消");

        // 为保存按钮添加点击事件监听器
        saveButton.addActionListener(e -> {
            // 获取用户输入的教学楼、教室号、楼层、容量和状态
            String building = buildingField.getText().trim();
            String roomNumber = roomNumberField.getText().trim();
            int floor = (Integer) floorSpinner.getValue();
            int capacity = (Integer) capacitySpinner.getValue();
            String type = (String) typeCombo.getSelectedItem();
            String status = (String) statusCombo.getSelectedItem();

            // 检查教学楼和教室号是否为空
            if (building.isEmpty() || roomNumber.isEmpty()) {
                JOptionPane.showMessageDialog(dialog, "请填写所有必填字段！");
                return;
            }

            // 调用服务层方法添加教室
            if (classroomService.addClassroom(building, roomNumber, floor, capacity, type, convertStatus2(status))) {
                // 添加成功，关闭对话框，重新加载教室数据，并显示成功消息
                dialog.dispose();
                loadClassroomData();
                JOptionPane.showMessageDialog(this, "教室添加成功！");
            } else {
                // 添加失败，显示错误消息
                JOptionPane.showMessageDialog(dialog, "教室添加失败！",
                        "错误", JOptionPane.ERROR_MESSAGE);
            }
        });

        // 为取消按钮添加点击事件监听器，点击时关闭对话框
        cancelButton.addActionListener(e -> dialog.dispose());

        buttonPanel.add(saveButton);
        buttonPanel.add(cancelButton);
        // 将按钮面板添加到对话框的南部
        dialog.add(buttonPanel, BorderLayout.SOUTH);

        // 调整对话框大小以适应其内容
        dialog.pack();
        // 将对话框居中显示在当前面板上
        dialog.setLocationRelativeTo(this);
        // 显示对话框
        dialog.setVisible(true);
    }

    // 显示编辑教室对话框的方法
    private void showEditDialog(String building, String roomNumber) {
        // 根据教学楼和教室号获取教室信息
        Map<String, Object> classroom = classroomService.getClassroomById(building, roomNumber);
        if (classroom == null) {
            JOptionPane.showMessageDialog(this, "获取教室信息失败！");
            return;
        }

        // 创建模态对话框
        JDialog dialog = new JDialog((Frame) SwingUtilities.getWindowAncestor(this), "编辑教室", true);
        dialog.setLayout(new BorderLayout(10, 10));

        // 创建表单面板，使用GridBagLayout布局
        JPanel formPanel = new JPanel(new GridBagLayout());
        formPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // 创建表单字段，并使用已有教室信息初始化
        JTextField buildingField = new JTextField(building);
        JTextField roomNumberField = new JTextField(roomNumber);
        JSpinner floorSpinner = new JSpinner(new SpinnerNumberModel(((Number) classroom.get("floor")).intValue(), 1, 100, 1));
        JTextField capacityField = new JTextField(classroom.get("capacity").toString());
        JComboBox<String> typeCombo = new JComboBox<>(new String[]{"普通教室", "上机室", "多媒体教室","阶梯教室","其他教室"});
        typeCombo.setSelectedItem(classroom.get("type"));
        JComboBox<String> statusCombo = new JComboBox<>(new String[]{"可用", "维修中", "已停用"});
        statusCombo.setSelectedItem(classroom.get("status"));

        // 添加表单字段到表单面板
        addFormField(formPanel, "教学楼：", buildingField, gbc, 0);
        addFormField(formPanel, "教室号：", roomNumberField, gbc, 1);
        addFormField(formPanel, "楼层：", floorSpinner, gbc, 2);
        addFormField(formPanel, "容量：", capacityField, gbc, 3);
        addFormField(formPanel, "教室类型：", typeCombo, gbc, 4);
        addFormField(formPanel, "状态：", statusCombo, gbc, 5);

        // 将表单面板添加到对话框的中心
        dialog.add(formPanel, BorderLayout.CENTER);

        // 创建按钮面板，使用FlowLayout居中对齐
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        // 创建保存按钮
        JButton saveButton = new JButton("保存");
        // 创建取消按钮
        JButton cancelButton = new JButton("取消");

        // 为保存按钮添加点击事件监听器
        saveButton.addActionListener(e -> {
            try {
                // 获取用户输入的楼层、容量并转换为整数
                int floor = (Integer) floorSpinner.getValue();
                int capacity = Integer.parseInt(capacityField.getText().trim());
                // 获取用户选择的状态索引并加1
                int status = statusCombo.getSelectedIndex() + 1;

                // 调用服务层方法更新教室信息
                if (classroomService.updateClassroom(
                        buildingField.getText().trim(),
                        roomNumberField.getText().trim(),
                        floor,
                        capacity,
                        (String) typeCombo.getSelectedItem(),
                        status)) {
                    // 更新成功，关闭对话框，重新加载教室数据，并显示成功消息
                    dialog.dispose();
                    loadClassroomData();
                    JOptionPane.showMessageDialog(this, "更新成功！");
                } else {
                    // 更新失败，显示错误消息
                    JOptionPane.showMessageDialog(dialog, "更新失败！",
                            "错误", JOptionPane.ERROR_MESSAGE);
                }
            } catch (NumberFormatException ex) {
                // 容量输入格式错误，显示提示消息
                JOptionPane.showMessageDialog(dialog, "请输入有效的容量数字！");
            }
        });

        // 为取消按钮添加点击事件监听器，点击时关闭对话框
        cancelButton.addActionListener(e -> dialog.dispose());

        buttonPanel.add(saveButton);
        buttonPanel.add(cancelButton);
        // 将按钮面板添加到对话框的南部
        dialog.add(buttonPanel, BorderLayout.SOUTH);

        // 调整对话框大小以适应其内容
        dialog.pack();
        // 将对话框居中显示在当前面板上
        dialog.setLocationRelativeTo(this);
        // 显示对话框
        dialog.setVisible(true);
    }

    // 删除教室的方法
    private void deleteClassroom(String building, String roomNumber) {
        // 显示确认删除对话框
        int confirm = JOptionPane.showConfirmDialog(this,
                "确定要删除这个教室吗？\n此操作不可恢复！",
                "删除确认",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.WARNING_MESSAGE);

        // 如果用户点击确定
        if (confirm == JOptionPane.YES_OPTION) {
            // 调用服务层方法删除教室
            if (classroomService.deleteClassroom(building, roomNumber)) {
                // 删除成功，重新加载教室数据，并显示成功消息
                loadClassroomData();
                JOptionPane.showMessageDialog(this, "教室删除成功！");
            } else {
                // 删除失败，显示错误消息
                JOptionPane.showMessageDialog(this, "教室删除失败！",
                        "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    // 加载教室数据到表格的方法
    private void loadClassroomData() {
        // 清空表格现有数据
        tableModel.setRowCount(0);
        // 获取所有教室信息
        List<Map<String, Object>> classrooms = classroomService.getAllClassrooms();
        for (Map<String, Object> classroom : classrooms) {
            // 将教室信息转换为表格行数据
            Object[] rowData = {
                    classroom.get("building"),
                    classroom.get("roomNumber"),
                    classroom.get("floor"),
                    classroom.get("capacity"),
                    classroom.get("type"),
                    convertStatus(((Number) classroom.get("status")).intValue()),
                    "编辑 删除"
            };
            // 将行数据添加到表格模型中
            tableModel.addRow(rowData);
        }
    }

    // 将状态码转换为状态字符串的方法
    private String convertStatus(int status) {
        switch (status) {
            case 1:
                return "可用";
            case 2:
                return "维修中";
            case 3:
                return "已停用";
            default:
                return "未知";
        }
    }

    private int convertStatus2(String status) {
        switch (status) {
            case "可用":
                return 1;
            case "维修中":
                return 2;
            case "已停用":
                return 3;
        }
        return 0;
    }

    // 向表单面板添加表单字段的辅助方法
    private void addFormField(JPanel panel, String label, JComponent field,
                              GridBagConstraints gbc, int row) {
        gbc.gridx = 0;
        gbc.gridy = row;
        panel.add(new JLabel(label), gbc);

        gbc.gridx = 1;
        panel.add(field, gbc);
    }
}
